package org.lex.io.filesystem.traveller;

import java.io.File;

import org.lex.filter.Filter;
import org.lex.filter.Filters;


public class FileTraveller<T> implements Runnable {
	private Filter<File> filter = null;
	private File dir = null;
	private FileProcessor<T> processor = null;

	public FileTraveller(File dir, FileProcessor<T> processor) {
		this(dir, null, processor);
	}

	public FileTraveller(File dir, Filter<File> filter, FileProcessor<T> processor) {
		this.dir = dir;
		if (null == filter)
			filter = Filters.acceptAllFilter();
		this.filter = filter;
		this.processor = processor;
	}

	public void run() {
		// null or none-exists
		if (null == dir && false == dir.exists())
			return;

		// not a directory
		if (false == dir.isDirectory()) {
			this.mayProcess(dir);
			return;
		}

		File[] files = dir.listFiles();
		// empty directory
		if (0 == files.length) {
			this.mayProcess(dir);
			return;
		}

		// directory has children
		for (File file : files)
			if (true == file.isFile())
				this.mayProcess(file);
			else
				new FileTraveller<T>(file, filter, processor).run();
		this.mayProcess(dir);
		return;
	}

	private void mayProcess(File file) {
		if (true == filter.accept(file))
			this.processor.operate(file);
	}
}
